#ifndef _STFQ_NW_SCHEDULER_H_
#define _STFQ_NW_SCHEDULER_H_
#include "NWScheduler.h"
#include "sthread.h"
#include <deque>
#include <queue>
#include <utility>
#include <map>

using namespace std;

typedef int fid;
typedef int buf;
typedef long long t_time;
typedef pair< t_time, fid > tagfid;
typedef pair< t_time, t_time > sftags;

class HeadComparator {
  bool reverse;
  public:
    HeadComparator(const bool& revopt=false) { reverse = revopt; }
    bool operator() (const tagfid& lhs, const tagfid& rhs) const {
      if (reverse) { return rhs.first < lhs.first; }
      return lhs.first < rhs.first;
    }
};

typedef priority_queue< tagfid, vector< tagfid >, HeadComparator > pQ;

class STFQNWScheduler:public NWScheduler{
 public:
  STFQNWScheduler(long bytesPerSec_);
  void waitMyTurn(fid flowId, float weight, int lenToSend);
  t_time signalNextDeadline(t_time deadlineMS);
  t_time getMaxFinishTag();

 private:
  // state -- global
  long   bytesPerSec;
  t_time virtualTime;
  t_time maxFinishTag;
  fid    currentFid;
  t_time delay;
  bool   delayChanged;
  pQ     bufsByStartTag;
  int    bufWaiting;

  // state -- per flow
  map<fid,deque<sftags> > fidToBufToTags;
  map<fid,int>            fidToBufCount;

  // synch
  smutex_t mutex;
  scond_t  waitMyTag;
  scond_t  waitTimeChanged;

};
#endif 
